package com.yuandian.business.monitor.service.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.yuandian.api.management.feign.RemoteAreaService;
import com.yuandian.api.management.vo.AreaDataVo;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.bpm.common.data.resolver.ParamResolver;
import com.yuandian.business.monitor.mapper.SystemBusiVisitDistribteMapper;
import com.yuandian.business.monitor.service.ISystemBusiVisitDistribteService;
import com.yuandian.api.business_monitor.vo.VisitDistribteDetailVO;
import com.yuandian.api.business_monitor.po.BusiVisitDistribteParams;
import com.yuandian.constant.ConfigKey;
import com.yuandian.constant.Constants;
import com.yuandian.enums.BaseTableName;
import com.yuandian.enums.SortEnum;
import com.yuandian.utils.PageDataInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 访问量分布详情
 *
 * @author zhoutian
 * @date 2020/9/30 10:32
 */
@Service
@Slf4j
public class SystemBusiVisitDistribteServiceImpl implements ISystemBusiVisitDistribteService {

	@Autowired
	SystemBusiVisitDistribteMapper systemBusiVisitDistribteMapper;
	@Autowired
	RemoteAreaService remoteAreaService;

	/**
	 * 访问量分布详情查询
	 *
	 * @param params 查询参数
	 * @return
	 */
	@Override
	public PageDataInfo getVisitDistribteDetail(BusiVisitDistribteParams params) {
		List<VisitDistribteDetailVO> list = new ArrayList<>();
		try {
			String currentTime = params.getCurrentTime();
			if (ObjectUtil.isEmpty(currentTime)) {
				throw new RuntimeException("当前时间不能为空！");
			}
			Date date = DateUtil.parse(currentTime, Constants.YYYY_MM_DD_HH_MM_SS);
			Calendar instance = Calendar.getInstance();
			instance.setTime(date);
			List<BusiVisitDistribteParams> dateList = new ArrayList<>();
			int hour = instance.get(Calendar.HOUR_OF_DAY);
			int minute = instance.get(Calendar.MINUTE);
			int second = instance.get(Calendar.SECOND);
			for (int i = 0; i < 7; i++) {
				BusiVisitDistribteParams busiVisitDistribteParams = new BusiVisitDistribteParams();
				instance.add(Calendar.DAY_OF_MONTH, -1);
				instance.set(Calendar.HOUR_OF_DAY, hour);
				instance.set(Calendar.MINUTE, minute);
				instance.set(Calendar.SECOND, second);
				busiVisitDistribteParams.setEndDateTime(instance.getTime());
				instance.set(Calendar.HOUR_OF_DAY, 00);
				instance.set(Calendar.MINUTE, 00);
				instance.set(Calendar.SECOND, 00);
				busiVisitDistribteParams.setBeginTime(instance.getTime());
				dateList.add(busiVisitDistribteParams);
			}
			String tableName = BaseTableName.BUSI_DISTRIBUTE_VISIT_HISTORY_M.getName();
			//1.获取缓存中的地图配置信息
            String areaName = "";
			try {
				areaName = Convert.toStr(ParamResolver.getStr(ConfigKey.SYS_PROJECT_MAP));
			}catch (Exception e){
				log.error("获取参数{}错误！", ConfigKey.SYS_CONFIG_KEY + (ConfigKey.SYS_PROJECT_MAP));
			}
			List<AreaDataVo> areaList = new ArrayList<>();
			List<VisitDistribteDetailVO> initList = new ArrayList<>();
			try {
				//1.1获取区域子集
				areaList = remoteAreaService.queryCodeByParentName(areaName).getData();
				//2.初始化区域对象结果集
				for (AreaDataVo area : areaList) {
					VisitDistribteDetailVO vo = new VisitDistribteDetailVO();
					vo.setSystemId(params.getSystemId());
					vo.setAreaCode(area.getCode());
					vo.setAreaName(area.getName());
					initList.add(vo);
				}
			}catch (Exception e){
				log.error("[首页详情]调用配置系统获取区域错误:{}", e);
			}
			//3.当天数据
			List<VisitDistribteDetailVO> data = systemBusiVisitDistribteMapper.queryBusiVisitDistribte(params);
			//4.历史数据
			List<VisitDistribteDetailVO> historyData = systemBusiVisitDistribteMapper.queryBusiVisitDistribteHistory(params, dateList);
			List<AreaDataVo> finalAreaList = areaList;
			historyData.forEach(e ->{
                AreaDataVo areaDataVo = new AreaDataVo();
                areaDataVo.setCode(e.getAreaCode());
                if(finalAreaList.contains(areaDataVo)){
                    e.setAreaName(finalAreaList.get(finalAreaList.indexOf(areaDataVo)).getName());
                }
            });
			//5.结果集收集
			data.addAll(historyData);
			data.addAll(initList);
			//6.根据区域聚合
			List<VisitDistribteDetailVO> tempList = new ArrayList<>();
			data.stream().collect(Collectors.groupingBy(e -> ObjectUtil.isEmpty(e.getAreaName()) ? "" : e.getAreaName(),
					Collectors.toList())).forEach((name, listName) -> {
				VisitDistribteDetailVO vo = new VisitDistribteDetailVO();
				listName.stream()
						.reduce(vo, VisitDistribteDetailVO::sum, (u, t) -> u);
				tempList.add(vo);
			});
			list = tempList;
			//7.全省统计
			VisitDistribteDetailVO all = new VisitDistribteDetailVO();
			data.stream().filter(e -> e.getSystemId() != null).collect(Collectors.groupingBy(VisitDistribteDetailVO::getSystemId,
					Collectors.toList())).forEach((name, listName) -> listName
					.stream()
					.reduce(all, VisitDistribteDetailVO::sum, (u, t) -> u));
			//8.排序
			if (ObjectUtil.isNotEmpty(params.getOrderByColumn())) {
				if (SortEnum.asc.name().equals(params.getIsAsc())) {
					list = ListUtil.sortByProperty(list, params.getOrderByColumn());
				}
				if (SortEnum.desc.name().equals(params.getIsAsc())) {
                    list = ListUtil.reverse(ListUtil.sortByProperty(list, params.getOrderByColumn()));
				}
			} else {
				list.sort(Comparator.comparingInt(VisitDistribteDetailVO::getVisitCount).reversed());
			}
			//找出未知区域信息，放在第二行
			VisitDistribteDetailVO unknownArea = null;
			for (VisitDistribteDetailVO vo : list) {
				if ("未知".equals(vo.getAreaName())) {
					unknownArea = vo;
				}
			}
			list.remove(unknownArea);
			all.setAreaName("全省");
			all.setAreaCode(null);
			list.add(0, all);
			if (unknownArea != null) {
				list.add(1, unknownArea);
			}
		} catch (Exception e) {
			log.error("访问量分布详情查询错误:{}", e.getMessage());
			throw new RuntimeException("访问量分布详情查询错误！");
		}
		return new PageDataInfo(list.size(), list);
	}
}
